
const Parse = require('parse/node');
const _=require('lodash');
const GoodObj = Parse.Object.extend("AutoBorrow_Goods");
const ParseHelper = require('../helpers/parse');

const CountsObj = Parse.Object.extend("AutoBorrow_Counts");
const RecordsObj = Parse.Object.extend("AutoBorrow_Records");
const ExcelService = require("./excel");


async function update(key,value,id){
    const Good = GoodObj.createWithoutData(id);
    if(key==="users"){
        Good.addUnique(key,value);  
    }else{  
    Good.set(key,value);
    }
    return Good.save(null,{ useMasterKey: true });
}

async function setGoodOwner(barcode,user){
    const query = new Parse.Query(GoodObj);
    query.equalTo('barcode',barcode);
    query.notEqualTo('isDeleted', true);
    const parseGood=await query.first({ useMasterKey: true });
    if(!parseGood){
        throw new Error("没有查询到物品");
    }
    parseGood.addUnique("users",user);
    return parseGood.save(null,{ useMasterKey: true }).then(ParseHelper.toJSON)
}
async function remove_owner(goodId,user){
    const Good = GoodObj.createWithoutData(goodId);
    Good.remove("users",user);
    return Good.save(null,{ useMasterKey: true });
}



async function add(goods,kindId){
    const objs=goods.map(good=>{
        const parseKind =  new GoodObj();
        parseKind.set("barcode",good)
        parseKind.set("kindId",kindId)
        parseKind.set("user",'admin')
        return parseKind;
    });
    return await Parse.Object.saveAll(objs,{ useMasterKey: true });
}


async function add_good(good){
    const Good =  new GoodObj();
    return Good.save(good,{ useMasterKey: true });
}

async function remove(ids){
    const unsavedKinds=ids.map(id=>{
        const parseKind =  GoodObj.createWithoutData(id);
        parseKind.set("isDeleted",true)
        return parseKind;
    });
    return await Parse.Object.saveAll(unsavedKinds,{ useMasterKey: true });
}

async function change_owner(goodIds,user){
    const unsavedGoods = goodIds.map(id => {
        const parseGood = GoodObj.createWithoutData(id);
        parseGood.set('user', user);
        return parseGood;
    });
    return Parse.Object.saveAll(unsavedGoods,{ useMasterKey: true });
}

async function change_good_owner(username,barcode){
    const query = new Parse.Query(GoodObj);
    query.equalTo('barcode',barcode);
    query.notEqualTo('isDeleted', true);
    const parseGood=await query.first({ useMasterKey: true });
    if(!parseGood){
        throw new Error("没有查询到物品");
    }
    parseGood.set("user",username);
    return parseGood.save(null,{ useMasterKey: true }).then(ParseHelper.toJSON)

}

async function change_owner_count(list, user,type){
return await Promise.all(list.map(async item => {
    const {kind, count} = item;
    const _count=Number(count);
    const query = new Parse.Query(CountsObj);
    query.notEqualTo('isDeleted', true);
    query.equalTo('kindId', kind._id);
    query.equalTo('user', user);
    let parseCount = await query.first({ useMasterKey: true });
    if(parseCount) {
        let newCount=0;
        if(type === "add") {
            newCount = parseCount.get('count') + _count;
        } else if(type === "sub") {
            newCount = parseCount.get('count') - _count;
        }
        parseCount.set('count', newCount);
    } else {
        parseCount = new CountsObj();
        parseCount.set('kindId', kind._id);
        parseCount.set('user', user);
        parseCount.set('count', _count);
    }
    return parseCount.save(null,{ useMasterKey: true });
    }));
}


async function change_good_owner_count(kind,count,username,type){
    const query = new Parse.Query(CountsObj);
    query.notEqualTo('isDeleted', true);
    query.equalTo('kindId', kind.objectId);
    query.equalTo('user', username);
    let parseCount = await query.first({ useMasterKey: true });
    if(parseCount) {
        let newCount=0;
        if(type === "add") {
            newCount = parseCount.get('count') + count;
        } else if(type === "sub") {
            newCount = parseCount.get('count') - count;
        }
        parseCount.set('count', newCount);
    } else {
        parseCount = new CountsObj();
        parseCount.set('kindId', kind._id);
        parseCount.set('user', user);
        parseCount.set('count', count);
    }
    return parseCount.save(null,{ useMasterKey: true });
}
async function save_record(list, user,type){
    const unsavedRecords = list.map(item => {
        const count=item.taken_count||item.count
        const {kind, goodId} = item;
        const kindId=kind.objectId||kind._id;
        const parseRecord = new RecordsObj();
        parseRecord.set('kind', kindId);
        parseRecord.set('count', Number(count));
        if(goodId) {
            parseRecord.set('good', goodId);
        }
        parseRecord.set('user', user);
        parseRecord.set('type', type);
        return parseRecord;
    });
    return Parse.Object.saveAll(unsavedRecords,{ useMasterKey: true });
}
async function getUsersApplyCount(kindId,usernames){
    const query = new Parse.Query(GoodObj);
    query.notEqualTo('isDeleted', true);
    query.equalTo('kindId', kindId);
    query.containedIn('user', usernames);
    return  query.count({ useMasterKey: true });
}

async function checkExcelFile(filePath,nameRowNumber,firstDataRowNumber,fieldsMapping){
    const goodsData=await ExcelService.parseExcelFileFirstSheet(filePath,nameRowNumber,firstDataRowNumber);
    //取得前5行作为样例数据
    const exampleRows=_.take(goodsData,5);
    const mappedExampleRows=exampleRows.map(row=>mappingUserData(row,fieldsMapping));
    const result={
        exampleRows,
        mappedExampleRows,
        filePath,
        count:goodsData.length
    };
    if(!mappedExampleRows[0].hasOwnProperty("barcode")){
        result.error= "缺少资产编号或设备编号"
    }
    return result;
}

//根据fieldsMapping修改userData中的key
function mappingUserData(userData, fieldsMapping){
    const mappedUserData={...userData};//复制要处理的数据
    Object.keys(mappedUserData).forEach(function(key) {
        const dbFieldName=fieldsMapping[key];
        if(dbFieldName){
            mappedUserData[dbFieldName] = mappedUserData[key];
            delete mappedUserData[key];
        }
    });
    return mappedUserData;
}
async function importExcelFile(filePath,nameRowNumber,firstDataRowNumber,fieldsMapping,kindId){
    var goodsData=await ExcelService.parseExcelFileFirstSheet(filePath,nameRowNumber,firstDataRowNumber);
    const mappedExampleRows=goodsData.map(row=>mappingUserData(row,fieldsMapping));
    const objs=mappedExampleRows.map(good=>{
        const parseKind =  new GoodObj();
        parseKind.set("barcode",good.barcode)
        parseKind.set("deviceId",good.deviceId)
        parseKind.set("kindId",kindId)
        parseKind.set("remark",good.remark)
        parseKind.set("user",'admin')
        return parseKind;
    });
    const goods= await Parse.Object.saveAll(objs,{ useMasterKey: true });
    return {successCount:goods.length};
}


async function getGoodByBarcode(barcode){
    const barcodeQuery = new Parse.Query(GoodObj);
    barcodeQuery.equalTo('barcode',barcode);
    const deviceQuery = new Parse.Query(GoodObj);
    deviceQuery.equalTo('deviceId',barcode);
    const query = Parse.Query.or(barcodeQuery, deviceQuery);
    query.notEqualTo('isDeleted', true);
    return query.first({ useMasterKey: true }).then(ParseHelper.toJSON);
}

async function getGoodsByIds(ids){
    const query = new Parse.Query(GoodObj);
    query.notEqualTo('isDeleted', true);
    query.containedIn('objectId', ids);
    query.limit(999);
    return query.find().then(ParseHelper.toJSONList);
}

async function getGoodById(id) {
    const query = new Parse.Query(GoodObj);
    query.notEqualTo('isDeleted', true);
    query.equalTo('objectId', id);
    return query.first({ useMasterKey: true }).then(ParseHelper.toJSON);
}

async function setGoodOwner(barcode,user){
    const query = new Parse.Query(GoodObj);
    query.equalTo('barcode',barcode);
    query.notEqualTo('isDeleted', true);
    const parseGood=await query.first({ useMasterKey: true });
    if(!parseGood){
        throw new Error("没有查询到物品");
    }
    parseGood.addUnique("users",user);
    return parseGood.save(null,{ useMasterKey: true }).then(ParseHelper.toJSON)
}

module.exports={
    update,
    add,
    remove,
    change_owner,
    change_good_owner,
    change_owner_count,
    save_record,
    change_good_owner_count,
    getUsersApplyCount,
    checkExcelFile,
    importExcelFile,
    add_good,
    getGoodByBarcode,
    getGoodsByIds,
    setGoodOwner,
    getGoodById

};